// ============================================
// TypeScript 基础类型示例
// ============================================

export {};

// 1. 基本类型
// 布尔值
let isDone: boolean = false;
let isActive: boolean = true;

// 数字
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

// 字符串
let color: string = "blue";
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}. I'll be ${age + 1} years old next month.`;

// 2. 数组
// 两种方式定义数组
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];

// 字符串数组
let fruits: string[] = ["apple", "banana", "orange"];

// 3. 元组 Tuple
// 元组类型允许表示一个已知元素数量和类型的数组
let x: [string, number];
x = ["hello", 10]; // 正确
// x = [10, "hello"]; // 错误

// 访问元组元素
console.log(x[0].substring(1)); // 正确
// console.log(x[1].substring(1)); // 错误，number没有substring方法

// 4. 枚举 Enum
// 数字枚举
enum Color {
    Red,
    Green,
    Blue
}
let c: Color = Color.Green;
console.log(c); // 输出: 1

// 手动设置枚举值
enum Status {
    Pending = 1,
    Approved = 2,
    Rejected = 3
}

// 字符串枚举
enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT"
}

// 5. Any 类型
// 当不确定类型时使用，但应该尽量避免
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // 也可以是布尔值

// any类型的数组
let anyList: any[] = [1, true, "free"];
anyList[1] = "100abc"; //这里可以修改为字符串
console.log(anyList[1]);

// 6. Void 类型
// 通常用于函数没有返回值的情况
function warnUser(): void {
    console.log("This is my warning message");
}

// void类型的变量只能赋值undefined或null
let unusable: void = undefined;

// 7. Null 和 Undefined
let u: undefined = undefined;
let n: null = null;

// 8. Never 类型
// never类型表示的是那些永不存在的值的类型
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}

// 推断的返回值类型为never
function fail() {
    return error("Something failed");
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
    while (true) {
    }
}

// 9. Object 类型
// object表示非原始类型
// 方案1：提供实际实现
function create(o: object | null): void {
    console.log("创建对象:", o);
}

create({ prop: 0 }); // 正确
create(null); // 正确
// create(42); // 错误
// create("string"); // 错误

// 方案2：如果只是演示类型，可以注释掉调用
// declare function create(o: object | null): void;
// console.log("object类型示例 - create函数只是类型声明");

// 10. 类型断言
// 两种语法形式
let someValue: any = "this is a string";

// 尖括号语法
let strLength1: number = (<string>someValue).length;

// as语法（推荐，特别是在JSX中）
let strLength2: number = (someValue as string).length;

// 11. 联合类型
let unionType: string | number;
unionType = "hello";
unionType = 42;
// unionType = true; // 错误

// 12. 字面量类型
type Easing = "ease-in" | "ease-out" | "ease-in-out";
let easing: Easing = "ease-in";
// easing = "ease-up"; // 错误

// 数字字面量类型
function rollDice(): 1 | 2 | 3 | 4 | 5 | 6 {
    return (Math.floor(Math.random() * 6) + 1) as 1 | 2 | 3 | 4 | 5 | 6;
}

// 13. 类型别名
type StringOrNumber = string | number;
type TextContent = string | { text: string }; // 重命名为 TextContent 避免冲突
type NameLookup = Dictionary<string, Person>;
type Callback<T> = (data: T) => void;

// 使用类型别名
let value: StringOrNumber = "hello";
value = 42;

// 14. 接口预览（详细内容在interfaces.ts中）
interface Person {
    name: string;
    age: number;
}

interface Dictionary<T, U> {
    [key: string]: U;
}

let person: Person = {
    name: "Alice",
    age: 30
};

// 15. 函数类型预览
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number {
    return x + y;
};

// 箭头函数
let myMultiply = (x: number, y: number): number => x * y;

// 16. 可选属性
interface Config {
    color?: string;
    width?: number;
}

function createSquare(config: Config): { color: string; area: number } {
    let newSquare = { color: "white", area: 100 };
    if (config.color) {
        newSquare.color = config.color;
    }
    if (config.width) {
        newSquare.area = config.width * config.width;
    }
    return newSquare;
}

let mySquare = createSquare({ color: "black" });

// 17. 只读属性
interface Point {
    readonly x: number;
    readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
// p1.x = 5; // 错误！x是只读的

// ReadonlyArray<T>类型
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
// ro[0] = 12; // 错误！
// ro.push(5); // 错误！
// ro.length = 100; // 错误！

console.log("=== 基础类型示例完成 ===");